#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<set>
#include<cstring>

const int N = 1e5 + 5;
const int eps = 1e-6;

int n, m, L, V, p[N], ord[N], ans1 = 0, ans2 = 0;
struct Car { int d, v, a; } c[N];
struct DetectSegment { int l, r; } ds[N];
std::set<int> canget[N];

inline bool in(std::set<int> a, std::set<int> b) {
    for(const auto& i : b) {
        if(*a.lower_bound(i) != i) return false;
    }
    return true;
}

inline int diff(std::set<int> a, std::set<int> b) {
    int ret = 0;
    for(const auto& i : b) {
        if(*a.lower_bound(i) != i) ++ret;
    }
    return ret;
}

inline void solve() {
    std::cin >> n >> m >> L >> V;
    for(int i = 1; i <= n; ++i) {
        std::cin >> c[i].d >> c[i].v >> c[i].a;

        if(c[i].a == 0) {
            if(c[i].v > V) ds[i].l = c[i].d, ds[i].r = L;
            else ds[i].l = -1, ds[i].r = -2;
            continue;
        }

        double t = (V - c[i].v) * 1. / c[i].a;
        double s = c[i].v * t + 0.5 * c[i].a * t * t + c[i].d;

        if(c[i].a > 0) ds[i].l = ((int)s == s ? (int)s + 1 : std::ceil(s)), ds[i].r = L;
        else ds[i].l = c[i].d, ds[i].r = ((int)s == s ? (int)s - 1 : std::floor(s));
    }
    for(int i = 1; i <= m; ++i) {
        std::cin >> p[i];
    }

    for(int i = 1; i <= n; ++i) {
        int posl = std::lower_bound(p + 1, p + m + 1, ds[i].l) - p;
        int posr = std::lower_bound(p + 1, p + m + 1, ds[i].r) - p;
        if(p[posr] != ds[i].r) --posr;
        // std::cout << posl << " " << posr << "::\n";
        if(posl <= posr) {
            // std::cout << "check: " << i << "\n";
            ++ans1;
            for(int j = posl; j <= posr; ++j) {
                canget[j].insert(i);
                // std::cout << "add: " << j << " " << i << "\n";
            }
        }
    }

    std::sort(canget + 1, canget + m + 1, [](std::set<int> a, std::set<int> b) {
        return a.size() > b.size();
    });

    /*
    for(int i = 1; i <= m; ++i) {
        for(const auto& x : canget[i]) std::cout << x << " ";
        std::cout << "\n";
    }

    std::cout << "\n-------------------\n";
    */

    std::set<int> c_ans;
    for(int i = 1; i <= m; ++i) {
        if(in(c_ans, canget[i])) continue;
        /*
        int l = i, r = i;
        for(int j = i; ; ++j) {
            if(canget[j].size() != canget[i].size()) break;
            else ++r;
        }
        */

        std::sort(canget + i, canget + n + 1, [c_ans](std::set<int> a, std::set<int> b) {
            return diff(c_ans, a) > diff(c_ans, b);
        });

        for(const auto& x : canget[i]) c_ans.insert(x);
        ++ans2;

        /*
        for(const auto& x : c_ans) std::cout << x << " ";
        std::cout << "\n";
        for(const auto& x : canget[i]) std::cout << x << " ";
        std::cout << "\n!-------------------!\n";
        */

        if(c_ans.size() == ans1) break;
    }

    std::cout << ans1 << " " << m - ans2 << "\n";

    std::fill(canget, canget + N, std::set<int>());
    ans1 = 0, ans2 = 0;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);

    std::freopen("detect.in", "r", stdin);
    std::freopen("detect.out", "w", stdout);

    int t; std::cin >> t;
    for(int c = 1; c <= t; ++c) {
        // if(c > 10) return 0;
        solve();
    }

    return 0;
}
